﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;
using System.Reflection;
using Microsoft.SharePoint;

namespace FTC.SharePoint.Evolution
{
   
    public class EvolutionsManager
    {
        protected List<BaseEvolution> Evolutions { get; set; }


        protected EvolutionsManager() { }

        private sealed class SingletonCreator
        {
            private static readonly EvolutionsManager instance = new EvolutionsManager();
            public static EvolutionsManager Instance { get { return instance; } }
        }

        public static EvolutionsManager Instance
        {
            get { return SingletonCreator.Instance; }
        }

        public void MakeEvolution(string nameSpace, string weburl)
        {
            MakeEvolution(nameSpace, weburl, new Version(0, 0, 0, 0), null);
        }

        public void MakeEvolution(string nameSpace, string weburl, Version fromVersion, Version toVersion)
        {
           
            // do linq query 
            IEnumerable results = GetAllClasses(nameSpace, typeof(BaseEvolution).Name);
            Evolutions = new List<BaseEvolution>();
            if (results != null)
            {
                foreach (Type b in results)
                {
                    object o = b.GetConstructor(new Type[0]).Invoke(null);

                    //Console.WriteLine(.Count());
                    System.Version v = ((EvoVersionAttribute)b.GetCustomAttributes(typeof(EvoVersionAttribute), true)[0]).Version;
                    b.GetProperty("EvoVersion").SetValue(o, v, null);
                    b.GetProperty("CurrentWebUrl").SetValue(o, weburl, null);

                    Evolutions.Add((BaseEvolution)o);

                }
                //if (fromVersion == null)
                //     fromVersion = "1.0.0.0";
                // Version fVersion = new Version(fromVersion);
                if (toVersion != null)
                {
                    //  Version tVersion = new Version(toVersion);
                    List<BaseEvolution> res = (from a in Evolutions
                                           where a.EvoVersion >= fromVersion && a.EvoVersion <= toVersion
                                           select a).ToList();
                    res.ForEach(x => x.Up());
                }
                else
                {
                    Evolutions.ForEach(x => x.Up());
                }
            }
        }

        public static IEnumerable GetAllClasses(string nameSpace, string baseClassName)
        {
            try
            {
                //System.Security.Policy.Evidence evidence = new System.Security.Policy.Evidence(null, null);
                Assembly asm1 = Assembly.LoadWithPartialName(nameSpace);
                return asm1.GetTypes();
                //Assembly.Load(na
            }
            catch
            {
                throw new NotImplementedException("Error while load assembly");
            }
            
            //Assembly asm = Assembly.GetExecutingAssembly();
            //if (!String.IsNullOrEmpty(nameSpace))
            //    return asm.GetTypes()
            //        .Where(x => x.Namespace == nameSpace)
            //        .Where(x => x.BaseType.Name == baseClassName);            
            //else
            //    return asm.GetTypes();
        }

    }
}
